package byx.container.core;

import byx.container.core.exception.RegisterException;
import byx.container.core.utils.TypeRef;

import java.util.UUID;
import java.util.function.Predicate;

public interface ObjectRegistry {
    void register(RegisterInfo registerInfo);

    default void register(String id, Class<?> type, int order, ObjectFactory<?> factory) {
        register(new RegisterInfo(id, type, order, factory));
    }

    default void register(String id, Class<?> type, ObjectFactory<?> factory) {
        register(id, type, 1, factory);
    }

    default void register(Class<?> type, ObjectFactory<?> factory) {
        String randomId = String.format("%s#%s",
                type.getName(), UUID.randomUUID().toString().replace("-", "").substring(0, 10));
        register(randomId, type, factory);
    }

    default <T> void register(TypeRef<T> typeRef) {
        try {
            ObjectFactory<?> factory = typeRef.getFactory();
            Class<?> type = typeRef.getGenericType();
            register(type, factory);
        } catch (Exception e) {
            throw new RegisterException(e);
        }
    }

    void unregister(Predicate<RegisterInfo> predicate);

    default void unregister(String id) {
        unregister(Predicates.ofId(id));
    }

    default void unregister(Class<?> type) {
        unregister(Predicates.ofType(type));
    }
}
